src/libostree/ostree-kernel-args.h \
src/libostree/ostree-sign.h \
src/libostree/ostree-sign-ed25519.h \
+ src/libostree/ostree-blob-reader.h \
$(NULL)
# This one is generated via configure.ac, and the gtk-doc
src/libostree/ostree-sign-ed25519.c \
src/libostree/ostree-sign-ed25519.h \
src/libostree/ostree-sign-private.h \
+ src/libostree/ostree-blob-reader.c \
+ src/libostree/ostree-blob-reader.h \
+ src/libostree/ostree-blob-reader-base64.c \
+ src/libostree/ostree-blob-reader-base64.h \
+ src/libostree/ostree-blob-reader-raw.c \
+ src/libostree/ostree-blob-reader-raw.h \
$(NULL)
if USE_COMPOSEFS
ostree_sign_set_pk
ostree_sign_set_sk
ostree_sign_summary
+ostree_sign_read_pk
+ostree_sign_read_sk
<SUBSECTION Standard>
ostree_sign_get_type
</SECTION>
+
+<SECTION>
+<FILE>ostree-blob-reader</FILE>
+ostree_blob_reader_read_blob
+<SUBSECTION Standard>
+ostree_blob_reader_get_type
+</SECTION>
LIBOSTREE_2025.2 {
global:
ostree_sepolicy_set_null_log;
+ ostree_sign_read_pk;
+ ostree_sign_read_sk;
+ ostree_blob_reader_get_type;
+ ostree_blob_reader_read_blob;
} LIBOSTREE_2025.1;
/* Stub section for the stable release *after* this development one; don't
--- /dev/null
+/*
+ * Copyright (C) 2024 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "ostree-blob-reader-base64.h"
+
+struct _OstreeBlobReaderBase64
+{
+ GDataInputStream parent_instance;
+};
+
+static void ostree_blob_reader_base64_iface_init (OstreeBlobReaderInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (OstreeBlobReaderBase64, _ostree_blob_reader_base64,
+ G_TYPE_DATA_INPUT_STREAM,
+ G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BLOB_READER,
+ ostree_blob_reader_base64_iface_init));
+
+static void
+ostree_blob_reader_base64_iface_init (OstreeBlobReaderInterface *iface)
+{
+ iface->read_blob = ostree_blob_reader_base64_read_blob;
+}
+
+static void
+_ostree_blob_reader_base64_class_init (OstreeBlobReaderBase64Class *klass)
+{
+}
+
+static void
+_ostree_blob_reader_base64_init (OstreeBlobReaderBase64 *self)
+{
+}
+
+OstreeBlobReaderBase64 *
+_ostree_blob_reader_base64_new (GInputStream *stream)
+{
+ return g_object_new (OSTREE_TYPE_BLOB_READER_BASE64, "base-stream", stream, NULL);
+}
+
+GBytes *
+ostree_blob_reader_base64_read_blob (OstreeBlobReader *self, GCancellable *cancellable,
+ GError **error)
+{
+ gsize len = 0;
+ g_autoptr (GError) local_error = NULL;
+ g_autofree char *line
+ = g_data_input_stream_read_line (G_DATA_INPUT_STREAM (self), &len, cancellable, &local_error);
+ if (local_error != NULL)
+ {
+ g_propagate_error (error, g_steal_pointer (&local_error));
+ return NULL;
+ }
+
+ if (line == NULL)
+ return NULL;
+
+ gsize n_elements;
+ g_base64_decode_inplace (line, &n_elements);
+ explicit_bzero (line + n_elements, len - n_elements);
+
+ return g_bytes_new_take (g_steal_pointer (&line), n_elements);
+}
--- /dev/null
+/*
+ * Copyright (C) 2024 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "ostree-blob-reader.h"
+
+G_BEGIN_DECLS
+
+#define OSTREE_TYPE_BLOB_READER_BASE64 (_ostree_blob_reader_base64_get_type ())
+
+_OSTREE_PUBLIC
+G_DECLARE_FINAL_TYPE (OstreeBlobReaderBase64, _ostree_blob_reader_base64, OSTREE,
+ BLOB_READER_BASE64, GDataInputStream);
+
+_OSTREE_PUBLIC
+OstreeBlobReaderBase64 *_ostree_blob_reader_base64_new (GInputStream *stream);
+
+_OSTREE_PUBLIC
+GBytes *ostree_blob_reader_base64_read_blob (OstreeBlobReader *self, GCancellable *cancellable,
+ GError **error);
+
+G_END_DECLS
--- /dev/null
+/*
+ * Copyright (C) 2024 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "ostree-blob-reader-raw.h"
+
+struct _OstreeBlobReaderRaw
+{
+ GDataInputStream parent_instance;
+};
+
+static void ostree_blob_reader_raw_iface_init (OstreeBlobReaderInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (OstreeBlobReaderRaw, _ostree_blob_reader_raw, G_TYPE_DATA_INPUT_STREAM,
+ G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BLOB_READER,
+ ostree_blob_reader_raw_iface_init));
+
+static void
+ostree_blob_reader_raw_iface_init (OstreeBlobReaderInterface *iface)
+{
+ iface->read_blob = ostree_blob_reader_raw_read_blob;
+}
+
+static void
+_ostree_blob_reader_raw_class_init (OstreeBlobReaderRawClass *klass)
+{
+}
+
+static void
+_ostree_blob_reader_raw_init (OstreeBlobReaderRaw *self)
+{
+}
+
+OstreeBlobReaderRaw *
+_ostree_blob_reader_raw_new (GInputStream *stream)
+{
+ return g_object_new (OSTREE_TYPE_BLOB_READER_RAW, "base-stream", stream, NULL);
+}
+
+GBytes *
+ostree_blob_reader_raw_read_blob (OstreeBlobReader *self, GCancellable *cancellable, GError **error)
+{
+ gsize len = 0;
+ g_autoptr (GError) local_error = NULL;
+ g_autofree char *line
+ = g_data_input_stream_read_line (G_DATA_INPUT_STREAM (self), &len, cancellable, &local_error);
+ if (local_error != NULL)
+ {
+ g_propagate_error (error, g_steal_pointer (&local_error));
+ return NULL;
+ }
+
+ if (line == NULL)
+ return NULL;
+
+ return g_bytes_new_take (g_steal_pointer (&line), len);
+}
--- /dev/null
+/*
+ * Copyright (C) 2024 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "ostree-blob-reader.h"
+
+G_BEGIN_DECLS
+
+#define OSTREE_TYPE_BLOB_READER_RAW (_ostree_blob_reader_raw_get_type ())
+
+_OSTREE_PUBLIC
+G_DECLARE_FINAL_TYPE (OstreeBlobReaderRaw, _ostree_blob_reader_raw, OSTREE, BLOB_READER_RAW,
+ GDataInputStream);
+
+_OSTREE_PUBLIC
+OstreeBlobReaderRaw *_ostree_blob_reader_raw_new (GInputStream *stream);
+
+_OSTREE_PUBLIC
+GBytes *ostree_blob_reader_raw_read_blob (OstreeBlobReader *self, GCancellable *cancellable,
+ GError **error);
+
+G_END_DECLS
--- /dev/null
+/*
+ * Copyright (C) 2024 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "ostree-blob-reader.h"
+
+G_DEFINE_INTERFACE (OstreeBlobReader, ostree_blob_reader, G_TYPE_OBJECT);
+
+static void
+ostree_blob_reader_default_init (OstreeBlobReaderInterface *iface)
+{
+ g_debug ("OstreeBlobReader initialization");
+}
+
+GBytes *
+ostree_blob_reader_read_blob (OstreeBlobReader *self, GCancellable *cancellable, GError **error)
+{
+ g_assert (OSTREE_IS_BLOB_READER (self));
+ return OSTREE_BLOB_READER_GET_IFACE (self)->read_blob (self, cancellable, error);
+}
--- /dev/null
+/*
+ * Copyright (C) 2024 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "ostree-types.h"
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define OSTREE_TYPE_BLOB_READER (ostree_blob_reader_get_type ())
+_OSTREE_PUBLIC
+G_DECLARE_INTERFACE (OstreeBlobReader, ostree_blob_reader, OSTREE, BLOB_READER, GObject)
+
+struct _OstreeBlobReaderInterface
+{
+ GTypeInterface g_iface;
+
+ GBytes *(*read_blob) (OstreeBlobReader *self, GCancellable *cancellable, GError **error);
+};
+
+_OSTREE_PUBLIC
+GBytes *ostree_blob_reader_read_blob (OstreeBlobReader *self, GCancellable *cancellable,
+ GError **error);
+
+G_END_DECLS
{
g_assert (OSTREE_IS_SIGN (self));
- if (!g_variant_is_of_type (revoked_key, G_VARIANT_TYPE_STRING))
- return glnx_throw (error, "Unknown ed25519 revoked key type");
-
OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private (OSTREE_SIGN_ED25519 (self));
- const gchar *rk_ascii = g_variant_get_string (revoked_key, NULL);
+ g_autofree guint8 *key_owned = NULL;
+ const guint8 *key = NULL;
gsize n_elements = 0;
- g_autofree guint8 *key = g_base64_decode (rk_ascii, &n_elements);
+
+ if (g_variant_is_of_type (revoked_key, G_VARIANT_TYPE_STRING))
+ {
+ const gchar *rk_ascii = g_variant_get_string (revoked_key, NULL);
+ key = key_owned = g_base64_decode (rk_ascii, &n_elements);
+ }
+ else if (g_variant_is_of_type (revoked_key, G_VARIANT_TYPE_BYTESTRING))
+ {
+ key = g_variant_get_fixed_array (revoked_key, &n_elements, sizeof (guchar));
+ }
+ else
+ {
+ return glnx_throw (error, "Unknown ed25519 revoked key type");
+ }
if (!validate_length (n_elements, OSTREE_SIGN_ED25519_PUBKEY_SIZE, error))
return glnx_prefix_error (error, "Incorrect ed25519 revoked key");
}
static gboolean
-_load_pk_from_stream (OstreeSign *self, GDataInputStream *key_data_in, gboolean trusted,
+_load_pk_from_stream (OstreeSign *self, GInputStream *key_stream_in, gboolean trusted,
GError **error)
{
- if (key_data_in == NULL)
+ if (key_stream_in == NULL)
return glnx_throw (error, "ed25519: unable to read from NULL key-data input stream");
gboolean ret = FALSE;
+ g_autoptr (OstreeBlobReader) blob_reader = ostree_sign_read_pk (self, key_stream_in);
+ g_assert (blob_reader);
+
/* Use simple file format with just a list of base64 public keys per line */
while (TRUE)
{
- gsize len = 0;
g_autoptr (GVariant) pk = NULL;
gboolean added = FALSE;
g_autoptr (GError) local_error = NULL;
- g_autofree char *line = g_data_input_stream_read_line (key_data_in, &len, NULL, &local_error);
+ g_autoptr (GBytes) blob = ostree_blob_reader_read_blob (blob_reader, NULL, &local_error);
if (local_error != NULL)
{
return FALSE;
}
- if (line == NULL)
+ if (blob == NULL)
return ret;
/* Read the key itself */
- /* base64 encoded key */
- pk = g_variant_new_string (line);
+ pk = g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, blob, FALSE);
if (trusted)
added = ostree_sign_ed25519_add_pk (self, pk, error);
else
added = _ed25519_add_revoked (self, pk, error);
- g_debug ("%s %s key: %s", added ? "Added" : "Invalid", trusted ? "public" : "revoked", line);
+ g_autofree gchar *pk_printable = g_variant_print (pk, FALSE);
+ g_debug ("%s %s key: %s", added ? "Added" : "Invalid", trusted ? "public" : "revoked",
+ pk_printable);
/* Mark what we load at least one key */
if (added)
g_autoptr (GFile) keyfile = NULL;
g_autoptr (GFileInputStream) key_stream_in = NULL;
- g_autoptr (GDataInputStream) key_data_in = NULL;
if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR))
{
if (key_stream_in == NULL)
return FALSE;
- key_data_in = g_data_input_stream_new (G_INPUT_STREAM (key_stream_in));
- g_assert (key_data_in != NULL);
-
- if (!_load_pk_from_stream (self, key_data_in, trusted, error))
+ if (!_load_pk_from_stream (self, G_INPUT_STREAM (key_stream_in), trusted, error))
{
if (error == NULL || *error == NULL)
return glnx_throw (error, "signature: ed25519: no valid keys in file '%s'", filename);
#include <unistd.h>
#include "ostree-autocleanups.h"
+#include "ostree-blob-reader-base64.h"
+#include "ostree-blob-reader-raw.h"
#include "ostree-core.h"
#include "ostree-sign-dummy.h"
#include "ostree-sign-ed25519.h"
{
return _ostree_sign_summary_at (self, repo, repo->repo_dir_fd, keys, cancellable, error);
}
+
+/**
+ * ostree_sign_read_pk:
+ * @self: Self
+ * @stream: a #GInputStream
+ *
+ * Start reading public keys from a stream.
+ *
+ * Returns: (transfer full): a #OstreamBlobReader or %NULL on error
+ *
+ * Since: 2025.2
+ */
+OstreeBlobReader *
+ostree_sign_read_pk (OstreeSign *self, GInputStream *stream)
+{
+#if defined(HAVE_ED25519)
+ if (OSTREE_IS_SIGN_ED25519 (self))
+ return OSTREE_BLOB_READER (_ostree_blob_reader_base64_new (stream));
+#endif
+ if (OSTREE_IS_SIGN_DUMMY (self))
+ return OSTREE_BLOB_READER (_ostree_blob_reader_raw_new (stream));
+ return NULL;
+}
+
+/**
+ * ostree_sign_read_sk:
+ * @self: Self
+ * @stream: a #GInputStream
+ *
+ * Start reading secret keys from a stream.
+ *
+ * Returns: (transfer full): a #OstreamBlobReader or %NULL on error
+ *
+ * Since: 2025.2
+ */
+OstreeBlobReader *
+ostree_sign_read_sk (OstreeSign *self, GInputStream *stream)
+{
+#if defined(HAVE_ED25519)
+ if (OSTREE_IS_SIGN_ED25519 (self))
+ return OSTREE_BLOB_READER (_ostree_blob_reader_base64_new (stream));
+#endif
+ if (OSTREE_IS_SIGN_DUMMY (self))
+ return OSTREE_BLOB_READER (_ostree_blob_reader_raw_new (stream));
+ return NULL;
+}
#include <glib-object.h>
#include <glib.h>
+#include "ostree-blob-reader.h"
#include "ostree-ref.h"
#include "ostree-remote.h"
#include "ostree-types.h"
_OSTREE_PUBLIC
gboolean ostree_sign_summary (OstreeSign *self, OstreeRepo *repo, GVariant *keys,
GCancellable *cancellable, GError **error);
+
+_OSTREE_PUBLIC
+OstreeBlobReader *ostree_sign_read_pk (OstreeSign *self, GInputStream *stream);
+
+_OSTREE_PUBLIC
+OstreeBlobReader *ostree_sign_read_sk (OstreeSign *self, GInputStream *stream);
+
G_END_DECLS
goto out;
}
- // Load each base64 encoded private key in a file and sign with it.
+ // Load each encoded private key in a file and sign with it.
for (char **iter = opt_key_files; iter && *iter; iter++)
{
const char *path = *iter;
- g_autofree char *b64key
- = glnx_file_get_contents_utf8_at (AT_FDCWD, path, NULL, NULL, error);
- if (!b64key)
+ g_autoptr (GFile) keyfile = NULL;
+ g_autoptr (GFileInputStream) key_stream_in = NULL;
+ g_autoptr (OstreeBlobReader) blob_reader = NULL;
+ g_autoptr (GBytes) blob = NULL;
+ g_autoptr (GError) local_error = NULL;
+ g_autoptr (GVariant) secret_key = NULL;
+
+ keyfile = g_file_new_for_path (path);
+ key_stream_in = g_file_read (keyfile, NULL, error);
+ if (key_stream_in == NULL)
+ goto out;
+
+ g_assert (sign);
+ blob_reader = ostree_sign_read_sk (sign, G_INPUT_STREAM (key_stream_in));
+ if (blob_reader == NULL)
+ goto out;
+
+ blob = ostree_blob_reader_read_blob (blob_reader, cancellable, &local_error);
+ if (local_error != NULL)
+ {
+ g_propagate_prefixed_error (error, g_steal_pointer (&local_error), "Reading %s",
+ path);
+ goto out;
+ }
+
+ if (blob == NULL)
{
g_prefix_error (error, "Reading %s", path);
goto out;
}
- g_autoptr (GVariant) secret_key = g_variant_new_string (b64key);
- g_assert (sign);
+
+ // Pass the key as a bytestring
+ secret_key = g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, blob, FALSE);
if (!ostree_sign_set_sk (sign, secret_key, error))
goto out;
{
g_autoptr (GFile) keyfile = NULL;
g_autoptr (GFileInputStream) key_stream_in = NULL;
- g_autoptr (GDataInputStream) key_data_in = NULL;
+ g_autoptr (OstreeBlobReader) blob_reader = NULL;
if (!g_file_test (opt_filename, G_FILE_TEST_IS_REGULAR))
{
if (key_stream_in == NULL)
goto out;
- key_data_in = g_data_input_stream_new (G_INPUT_STREAM (key_stream_in));
- g_assert (key_data_in != NULL);
+ blob_reader = ostree_sign_read_sk (sign, G_INPUT_STREAM (key_stream_in));
+ g_assert (blob_reader != NULL);
/* Use simple file format with just a list of base64 public keys per line */
while (TRUE)
{
- gsize len = 0;
- g_autofree char *line
- = g_data_input_stream_read_line (key_data_in, &len, NULL, error);
+ g_autoptr (GBytes) blob
+ = ostree_blob_reader_read_blob (blob_reader, cancellable, error);
g_autoptr (GVariant) sk = NULL;
if (*error != NULL)
goto out;
- if (line == NULL)
+ if (blob == NULL)
break;
// Pass the key as a string
- sk = g_variant_new_string (line);
+ sk = g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, blob, FALSE);
if (!ostree_sign_set_sk (sign, sk, error))
{
ret = FALSE;